QT学习笔记(六)

您所在的位置:网站首页 qt 播放器进度条 QT学习笔记(六)

QT学习笔记(六)

#QT学习笔记(六)| 来源: 网络整理| 查看: 265

一、配置文件更改

用到多媒体的话,需要修改配置文件的第一行,后面加一句 sql multimedia multimediawidgets 修改后的配置文件前3行如下

QT += core gui sql multimedia multimediawidgets //下面都不用改 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 二、UI基本设计(待会会根据功能回来修改部分属性) 找一个普通的widget,然后右键 “提升为” QVideoWidget 整体UI是这样的,布局就差不多自己搞一下吧 在这里插入图片描述 三、视频播放进度条跟着动、拖动进度条视频跟着动 mainwindow.cpp文件 啥代码都不写的话,你打开一个视频,会发现随着视频的播放,进度条动都不动。所以要进行下面的操作 (1)去帮助手册查看horizental slider这个控件的信号,发现slidermoved这个信号可以传回来进度条的最新位置。根据这个位置去改变视频的进度,用setPosition。 (2)去帮助手册查看player的信号,发现positionChanged这个信号可以返回视频的最新播放进度,可以用来设置进度条的值setValue。 上面两个看起来有点像“互锁”的感觉,但是各搞各的,可以实现。 #include "mainwindow.h" #include "ui_mainwindow.h" #include // #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); player =new QMediaPlayer; player->setMedia(QMediaContent(QUrl::fromLocalFile("D:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\webapps\\MyWebsite\\大耳朵图图.mp3"))); player->setVideoOutput(ui->widget); player->play(); //视频长度改变,打印出来 connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(onPlayerDurationChanged(qint64))); //进度条位置改变,打印出来 connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(onPlayerPositionChanged(qint64))); //拖动进度条,改变视频的进度 connect(ui->horizontalSlider,SIGNAL(sliderMoved(int)),this,SLOT(onSliderMoved(int))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onPlayerDurationChanged(qint64 duration){ qDebug()setMaximum(duration); //最大值 } /* * 获取视频进度 */ void MainWindow::onPlayerPositionChanged(qint64 position){ qDebug()setValue(position); //进度条进度跟着变 } /* * 根据进度条的value,改变视频的进度 */ void MainWindow::onSliderMoved(int value){ player->setPosition(value); //视频跟着进度条变 } 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include // QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; QMediaPlayer *player; //!!! private slots: void onPlayerDurationChanged(qint64 duration); //!!! void onPlayerPositionChanged(qint64 position); // void onSliderMoved(int value); }; #endif // MAINWINDOW_H 这个时候你会发现,实现了“进度条随着视频的播放而变化”这一功能,但是拖不动进度条哈哈哈哈。解决方案见下面的问题和思考。 四、实现暂停/播放按钮 安排好按钮上需要的图片资源 (1)之前创建过资源文件夹了,里面也创建了一个子文件夹/pic用来存放图片,把想用的图片拖进去。而且必须拖进去,比如下面这行代码: ui->pushButton->setStyleSheet("border-image: url(F:\\QT project\\day03_video\\Resources\\play.jpg)");

用的是本地路径,这个是不管用的。 要改成:

ui->pushButton->setStyleSheet("border-image: url(:/pic/play.jpg)");

注意,子文件夹/pic在本地文件管理器中是看不到的 (2)资源放入/pic文件夹后,更改pushButton的styleSheet属性,将border-image设为想要的图片 在这里插入图片描述 在这里插入图片描述

mainwindow.cpp文件(在之前进度条的代码上改的)) #include "mainwindow.h" #include "ui_mainwindow.h" #include // #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); player =new QMediaPlayer; player->setMedia(QMediaContent(QUrl::fromLocalFile("D:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\webapps\\MyWebsite\\大耳朵图图.mp3"))); player->setVideoOutput(ui->widget); player->play(); //视频播放or暂停状态切换,不断获取,存在state这个成员变量里 connect(player,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(onPlayerStateChanged(QMediaPlayer::State))); //视频长度改变,打印出来 connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(onPlayerDurationChanged(qint64))); //进度条位置改变,打印出来 connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(onPlayerPositionChanged(qint64))); //拖动进度条,改变视频的进度 connect(ui->horizontalSlider,SIGNAL(sliderMoved(int)),this,SLOT(onSliderMoved(int))); //按下播放按钮,改变按钮的状态;因为视频的状态被player这个播放器不断获取,所以onPlayerStateChanged一直被调用,相应的图片也会改变 connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(onPlay())); } MainWindow::~MainWindow() { delete ui; } /* * 切换视频状态(播放->暂停,暂停->播放) */ void MainWindow::onPlay(){ if(player->state()== QMediaPlayer::PlayingState){ player->pause(); }else{ player->play(); } } /* * 跟踪视频状态(播放or暂停) */ void MainWindow::onPlayerStateChanged(QMediaPlayer::State state){ this->state = state; if(state == QMediaPlayer::PlayingState){ ui->pushButton->setStyleSheet("border-image: url(:/pic/play.jpg)"); }else{ ui->pushButton->setStyleSheet("border-image: url(:/pic/pause.jpg)"); } } /* *获取视频长度 */ void MainWindow::onPlayerDurationChanged(qint64 duration){ qDebug()setMaximum(duration); //最大值 } /* * 获取视频进度 */ void MainWindow::onPlayerPositionChanged(qint64 position){ qDebug()setValue(position); //进度条进度跟着变 } /* * 根据进度条的value,改变视频的进度 */ void MainWindow::onSliderMoved(int value){ player->setPosition(value); //视频跟着进度条变 } 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include // QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; QMediaPlayer *player; //!!! QMediaPlayer::State state; //!!! private slots: void onPlay(); //!!! void onPlayerStateChanged(QMediaPlayer::State state); //!!! void onPlayerDurationChanged(qint64 duration); //!!! void onPlayerPositionChanged(qint64 position); // void onSliderMoved(int value); }; #endif // MAINWINDOW_H 五、实现进度条的“点哪打哪”

前面实现的视频播放器只能拖动进度条,不能像市面上常见的播放器一样点哪里播放哪里,下面就要实现这个功能。

首先,UI界面不用动了QSlider的mousePressEvent()默认的方式是,点击之后跳跃一定的固定距离,无法实现“指哪打哪”,因此我们需要对mousePressEvent()进行重写。不知道可不可以简单的在mainwindow.cpp里直接重载mousePressEvent()这个函数。我没尝试,我直接用的下面这个方法(转载自博客) (1)给QSlider添加一个子类。在项目窗口中,右击工程的根目录,添加新文件,选择C++ Class,填写基类为QSlider。我这里将其命名为CustomSlider。自动生成了customslider.h和customslider.cpp这两个文件。 在这里插入图片描述 在这里插入图片描述

(2)直接把代码粘进去。

customslider.h

#ifndef CUSTOMSLIDER_H #define CUSTOMSLIDER_H #include #include #include class CustomSlider : public QSlider { Q_OBJECT public: CustomSlider(QWidget *parent = 0) : QSlider(parent) { } protected: void mousePressEvent(QMouseEvent *ev);//重写QSlider的mousePressEvent事件 signals: void costomSliderClicked();//自定义的鼠标单击信号,用于捕获并处理 }; #endif // CUSTOMSLIDER_H

customslider.cpp

#include "customslider.h" void CustomSlider::mousePressEvent(QMouseEvent *ev) { //注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况 QSlider::mousePressEvent(ev); //获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了) double pos = ev->pos().x() / (double)width(); //让进度条直接蹦过来 setValue(pos * (maximum() - minimum()) + minimum()); //发送自定义的鼠标单击信号 emit costomSliderClicked(); }

(3)再就是在头文件mainwindow.h里加一个新的槽函数,就是点击进度条触发的槽函数。

private slots: void sliderClicked();

(4)编写槽函数

/* * slider点击事件发生后,改变视频的进度 */ void MainWindow::sliderClicked(){ player->setPosition(ui->horizontalSlider->value()); }

(5)连接信号和槽函数

//自定义的信号costomSliderClicked() connect(ui->horizontalSlider,SIGNAL(costomSliderClicked()),this,SLOT(sliderClicked()));

(6)非常重要的一点!!因为我们继承了QSlider这个类,生成了新的类CustomSlider,所以UI里的进度条的类提升一下,不然的话和代码不配套。 右击进度条,选择提升为,自己写上提升为CustomSlider 在这里插入图片描述

六、问题和思考 拖动进度条实现视频进度改变的槽函数写好了,信号连好了,但是拖动不了进度条。 一开始在找信号和函数的问题,确保了没有问题(照老师抄的)以后。开始想,进度条拖不动应该是控件本身的问题吧。于是根据直觉改了空间horizental slider的一个属性,把mouseTracking那里打上勾就可以了哈哈哈哈 在这里插入图片描述一开始播放按钮想用toolButton,但是它的信号只有一个triggered(*action),里面的参数我不太懂,就换了pushButton,用cliked()信号。如果出现问题别忘了看程序输出窗口!! 在这里插入图片描述使用下面这行代码, player->setMedia(QMediaContent(QUrl::fromLocalFile("D:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\webapps\\MyWebsite\\大耳朵图图.mp3")));

mp3可以播放,但视频mp4不能播放,并且报错

DirectShowPlayerService::doRender: Unresolved error code 0x80040266

这个是不能解析的错误,一开始我以为是fromLocalFile这个函数不能解析路径,一直在改这个函数的参数哼,后来发现我理解错了,不能解析的意思是视频没法解析!!!需要下载一个解析视频的程序,LAVFilters,放哪都行,下载完立马奏效!!。当然,除了LAVFilters,其他解析视频的程序也可以。 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3